/**
 *
 */
package vn.smartware.co.framework.swt.base;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;

import vn.smartware.co.framework.action.Requester;
import vn.smartware.co.framework.common.BaseConstant;
import vn.smartware.co.framework.exception.ClientException;
import vn.smartware.co.framework.exception.FatalException;
import vn.smartware.co.framework.exception.ServerException;
import vn.smartware.co.framework.exception.SessionTimeOutException;
import vn.smartware.co.framework.form.ActionForm;
import vn.smartware.co.framework.utils.MsgBoxUtils;

/**
 * SmsComposite
 * 
 * @author thuctt
 */
abstract public class JNetComposite extends Composite {

	private static Log log = LogFactory.getLog(JNetComposite.class);

	/**
	 * APP_NAME
	 */
	protected String APP_NAME;
	
	/**
	 * button Close
	 */
	protected Button btnClose;

	/**
	 * Constructor
	 * 
	 * @param parent
	 * @param style
	 * @param prgName 
	 */
	public JNetComposite(Composite parent, int style, String prgName) {
		super(parent, style);
		this.APP_NAME = prgName;
		setBackground(BaseConstant.COLOR_BGR_BASE); 
		createContents();
	}

	/**
	 * Constructor
	 * 
	 * @param parent
	 * @param style
	 */
	public JNetComposite(Composite parent, int style) {
		super(parent, style);
	}

	/**
	 * execute an action
	 * 
	 * @param form
	 * @return ActionForm
	 * @throws FatalException 
	 * @throws ServerException 
	 * @throws SessionTimeOutException 
	 */
	protected final ActionForm execute(ActionForm form) throws FatalException,
			ServerException, SessionTimeOutException {
		
		form.setAppName(this.APP_NAME);
		form = Requester.execute(form, this);
		return form;
	}

	/**
	 * validatorErrorMsgBox
	 * 
	 * @param errMsg
	 */
	protected final void validatorErrorMsgBox(String errMsg) {
		try {
			if (errMsg != null) {
				MsgBoxUtils.errorMsgBox("errors.SYSTEM_ERROR", new Object[] { errMsg });
			}
		} catch (ClientException e) {
			log.error("JNetComposite validatorErrorMsgBox ClientException.", e);
		}
	}

	/**
	 * fatalErrorMsgBox
	 */
	protected final void fatalErrorMsgBox() {
		try {
			MsgBoxUtils.errorMsgBox("errors.SYSTEM_ERROR", new Object[] {});
		} catch (ClientException ce) {
			log.error("JNetComposite fatalErrorMsgBox ClientException.", ce);
		}

		this.setFocus();
		lockScreen(true);
		btnClose.setEnabled(true);
	}
	
	/**
	 * SelectAllFocusAdapter
	 */
	protected final class SelectAllFocusAdapter extends FocusAdapter {
		/**
		 * SelectAllFocusAdapter()
		 */
		public SelectAllFocusAdapter() {
			super();
		}

		/**
		 * focusGained
		 * @param e 
		 */
		public void focusGained(FocusEvent e) {
			if (e.getSource() instanceof Text) {
				((Text) e.getSource()).selectAll();
			}
		}
	}

	/**
	 * addFocusListener
	 * 
	 * @param control
	 * @param listener
	 */
	protected final void addFocusListener(Control control, FocusListener listener) {
		control.addFocusListener(listener);
	}

	/**
	 * closeAction
	 * 
	 * @param appName
	 * @return boolean
	 */
	private final boolean closeAction(String appName) {
		try {
			int res = MsgBoxUtils.questionMsgBox("question.EXIT_PRG", new Object[] { appName });
			if (res == SWT.YES) {
				closeTab(SWTManager.getInstance().getSelectingTabIndex());

				SWTManager.getInstance().getTabFolder().setFocus();
				CTabItem currentItem = SWTManager.getInstance()
						.getSelectingTabItem();
				if (currentItem != null) {
					currentItem.setControl(currentItem.getControl());
				}

				return true;
			}

		} catch (ClientException e) {
			log.error("JNetComposite closeAction ClientException.", e);
		}
		return false;
	}

	/**
	 * addSelectAllListener
	 * 
	 * @param ctrl
	 */
	private void addSelectAllListener(Control ctrl) {
		if (ctrl instanceof Text) {
			//
			ctrl.addFocusListener(new SelectAllFocusAdapter());
		} else if (ctrl instanceof Composite) {
			//
			Composite comp = (Composite) ctrl;
			Control[] children = comp.getChildren();
			if (children != null) {
				for (int i = 0; i < children.length; i++) {
					addSelectAllListener(children[i]);
				}
			}
		}
	}

	/**
	 * initialize
	 */
	abstract protected void initialize();
	
	/**
	 * Load data
	 */
	abstract protected boolean loadData() throws FatalException;

	/**
	 * executeInit
	 */
	private final void createContents() {
		try {
			initialize();
			addSelectAllListener(this);
			this.setSize(SWTBase.COMPOSITE_SIZE_X, SWTBase.COMPOSITE_SIZE_Y);
			
			if (!loadData()){
				fatalErrorMsgBox();
				return;
			}
			
			clearAction();
		} 
		catch (SWTError e) {
			log.error("initialize failed. SWTException: " + e.getMessage());
			this.disposeChild();
			throw e;
		}
		catch (SessionTimeOutException e) {
			log.error("getInitData SessionTimeOutException", e);
		}
		catch (FatalException e) {
			log.error("initialize failed. FatalException: " + e.getMessage());
			fatalErrorMsgBox();
		}
	}

	/**
	 * closeTab
	 * 
	 * @param tabIndex
	 */
	protected void closeTab(int tabIndex) {

		SWTBase baseForm = SWTManager.getInstance().getBaseManager();
		baseForm.disposeTab(tabIndex);
	}

	/**
	 * disposeChild
	 */
	protected void disposeChild() {
		Control[] control = this.getChildren();
		for (int i = 0; i < control.length; i++) {
			control[i].dispose();
		}
	}

	/**
	 * close action
	 * @param btnClose
	 */
	protected final boolean closeAction() {

		return closeAction(APP_NAME);
	}
	
	/**
	 * clear action
	 *
	 */
	protected void clearAction() {}
	
	/**
	 * display action
	 *
	 */
	protected void searchAction() {}
	
	/**
	 * save action
	 *
	 */
	protected void saveAction() {}
	
	/**
	 * delete action
	 *
	 */
	protected void deleteAction() {}
	
	/**
	 * edit action
	 *
	 */
	protected void editAction() {}
	
	/**
	 * create new action
	 *
	 */
	protected void newAction() {}

	/**
	 * apply action when click button Apply
	 *
	 */
	protected void applyAction() {}

	/**
	 * lock/unlock all controls of screen
	 * @param flg
	 */
	abstract protected void lockScreen(boolean flg);
	
}
